﻿using FineCollection.Intf;




namespace FineCollection.Hash
{
    /// <summary>
    /// Hash table.
    /// </summary>
    /// <typeparam name="T">type of an item.</typeparam>
    public class HashSet<T> : HashTable<T>, WSet<T>
        where T : System.IEquatable<T>
    {
        /// <summary>
        /// Creates an empty hash set with the default capacity.
        /// </summary>
        public HashSet()
        {}


        /// <summary>
        /// Creates an empty hash set with the specified capacity.
        /// </summary>
        /// <param name="capacity">initial capacity.</param>
        public HashSet(int capacity) 
            : base(capacity)
        {}


        public void Include(T item)
        {
            int itemHash = item.GetHashCode();
            bool found;
            CheckExistance(itemHash,
                           anItem => anItem.Equals(item),
                           out found);

            if (!found)
                Add(item);
        }


        public void Exclude(T item)
        {
            int itemHash = item.GetHashCode();
            HashChain<T> hchain = FindFirst(itemHash,
                                            anItem => anItem.Equals(item));

            if (hchain.chain != null)
                Remove(hchain);
        }


        /// <summary>
        /// Checks whether the specified item existent in the set.
        /// </summary>
        /// <param name="item">item to check.</param>
        /// <returns>existence.</returns>
        public bool Contains(T item)
        {
            int itemHash = item.GetHashCode();
            bool found;
            CheckExistance(itemHash, 
                           anItem => anItem.Equals(item),
                           out found);

            return found;
        }
    }
}